package com.xxl.sso.server.controller;

import cc.comac.techfoundation.audit.client.LogHttpClient;
import cc.comac.techfoundation.entity.AuditLogin;
import com.alibaba.algo.cooperation.common.BaseResult;
import com.alibaba.fastjson.JSONObject;
import com.xxl.sso.core.conf.Conf;
import com.xxl.sso.core.exception.XxlSsoException;
import com.xxl.sso.core.filter.XxlSsoProperties;
import com.xxl.sso.core.login.SsoTokenLoginHelper;
import com.xxl.sso.core.login.SsoWebLoginHelper;
import com.xxl.sso.core.store.SsoLoginStore;
import com.xxl.sso.core.store.SsoSessionIdHelper;
import com.xxl.sso.core.user.XxlSsoUser;
import com.xxl.sso.core.util.AESUtil;
import com.xxl.sso.server.config.LoginConfig;
import com.xxl.sso.server.config.XxlSsoCacheConfig;
import com.xxl.sso.server.core.model.LoginTypeInfo;
import com.xxl.sso.server.core.model.UserInfo;
import com.xxl.sso.server.core.result.ReturnT;
import com.xxl.sso.server.service.UserService;
import com.xxl.sso.server.util.CaptchaUtils;
import com.xxl.sso.server.util.IPUtils;
import com.xxl.sso.server.util.JedisUtil;
import com.xxl.sso.server.util.RSAUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * sso server (for web)
 *
 * @author xuxueli 2017-08-01 21:39:47
 */
@Controller
@Slf4j
public class WebController {

    public static final String TO_URL = "to_url";
    @Autowired
    private UserService userService;

    @Value("${spring.freemarker.login-page.title:统一用户中心}")
    private String loginPageTitle;

    @Value("${spring.freemarker.login-page.login-logo:统一用户中心}")
    private String loginPageLoginLogo;

    @Value("${spring.freemarker.login-page.login-box-msg:统一用户中心}")
    private String loginPageLoginBoxMsg;


    @Value("${spring.freemarker.index-page.title:统一用户中心}")
    private String indexPageTitle;


    @Value("${spring.freemarker.index-page.h4:统一用户中心}")
    private String indexPageH4;

    @Value("${xxl.sso.logout2ComacPortal.matchedUrls:}")
    private String matchedUrlsStr;

    @Value("${xxl.sso.logout2ComacPortal.comacPortalUrl:}")
    private String comacPortalUrl;

    @Value("${rsa.privateKey:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAICcHrWOTVO+M/EnPCyY8UNCJkmPqVYBcrdtORVLyp+YWMAFe+TNHBog303cyHs563Dh47Mj7TJD+6JfGQkh0vN1M6JGwHBm26J975B8CKaKtYTnIkk56aSYzd8VYtc1ZbG0huh6QVB0v1YI2o/4+YHun3QdWYzLJ+R6FTcgP4gRAgMBAAECgYALi/jF3CzdI+qN8DPa3TBsFXhSim9tpVujVE8XtmJOyeLN+rAQ7sljHyhtWTE2vxCAZgeHgeY96RSik18wDrVdvKLF/KH0DngRebJmJiILTyJJKISJ+E1douDc31vWVdjm3yu4MRxusbKTC1LegGnTX4iyUueH4QmqgdG6fRvTcQJBAOxC26KECSnOwZ1wXSd+PMk/LgTRaiM99maO5iynlGYHf1lUBzvndi8oEoiaw4HaPH1aGEaLfplNtRrPKprZGl8CQQCLWtInSLrBTwNCIkZGyKdPwB2uCF2/KWu0qSRoQ/nRUMPX3c5pe8wVJ61nR4z5oaFFlgdG+XExnGx6wqRTs1OPAkBvft3HxCfO4xPcCLrteFWXY4mEHI/KMeOmYqmdSThvLfqbXVxMmN7dQjv824yIK0WAopPyNsJ39oQRMtMYYHxhAkEAhA4Uh9WL5BOT6t+/6OPMaO6NMZYMAFKoFhMSxRtlaM04SR+PsrX1tzZaRDyxgv1/bgm167QFaBXrVomMXyTYUQJAbsqsHRRT8+Twh6nW74v1NGMnofni4XvoJq8d/9et0uboLPz2JEM+eUqJIu1989UOEVq+gnz+BF9vd4l2j2JKMA==}")
    private String rsaPrivateKey;

    @Autowired
    private XxlSsoProperties xxlSsoProperties;

    @Autowired
    private LoginConfig loginConfig;

    @Autowired(required = false)
    private LogHttpClient logHttpClient;

    private static final String ENC_UTF8 = "UTF-8";

    @RequestMapping("/")
    public String index(Model model, HttpServletRequest request, HttpServletResponse response) {
        model.addAttribute("loginPageTitle", loginPageTitle);
        model.addAttribute("loginPageLoginLogo", loginPageLoginLogo);
        model.addAttribute("loginPageLoginBoxMsg", loginPageLoginBoxMsg);

        model.addAttribute("indexPageTitle", indexPageTitle);
        model.addAttribute("indexPageH4", indexPageH4);
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);

        if (xxlUser == null) {
            return "redirect:" + xxlSsoProperties.getLoginPage();
        } else {
            return "redirect:" + xxlSsoProperties.getUserMgrPage();
        }
    }

    /**
     * Login page
     *
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(Conf.SSO_LOGIN)
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {
        log.info("======================1.WebController#login");
        model.addAttribute("loginPageTitle", loginPageTitle);
        model.addAttribute("loginPageLoginLogo", loginPageLoginLogo);
        model.addAttribute("loginPageLoginBoxMsg", loginPageLoginBoxMsg);
        model.addAttribute("indexPageTitle", indexPageTitle);
        model.addAttribute("indexPageH4", indexPageH4);
        XxlSsoUser xxlUser = SsoWebLoginHelper.loginCheck(request, response);
        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
        String toUrl = request.getParameter(TO_URL);
        log.info("======================2.WebController#login,redirectUrl={},toUrl={}", redirectUrl, toUrl);
        if (xxlUser != null) {
            log.info("======================3.WebController#login,xxlUser={}", JSONObject.toJSONString(xxlUser));
            if (redirectUrl != null && !redirectUrl.trim().isEmpty()) {
                String sessionId = SsoWebLoginHelper.getSessionIdByCookie(request);
                String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
                if (!StringUtils.isEmpty(toUrl)) {
                    redirectUrlFinal = redirectUrlFinal + "&" + TO_URL + "=" + toUrl;
                }
                log.info("======================4.WebController#login,redirectUrlFinal={}", redirectUrlFinal);
                return "redirect:" + redirectUrlFinal;
            } else {
                return "redirect:" + xxlSsoProperties.getUserMgrPage();
            }
        }

        model.addAttribute("errorMsg", request.getParameter("errorMsg"));
        model.addAttribute(Conf.REDIRECT_URL, redirectUrl);
        model.addAttribute(TO_URL, toUrl);
        if (StringUtils.isEmpty(redirectUrl)) {
            redirectUrl = "";
        }
        if (StringUtils.isEmpty(toUrl)) {
            toUrl = "";
        }
        String loginUrl = "redirect:" + xxlSsoProperties.getLoginPage().concat("?").concat(Conf.REDIRECT_URL).concat("=").concat(redirectUrl).concat("&").concat(Conf.TO_URL).concat("=").concat(toUrl);
        log.info("======================4.WebController#login,loginUrl={}", loginUrl);
        return loginUrl;
    }

    @RequestMapping(Conf.VALIDATE_LOGIN_PATH)
    @ResponseBody
    public XxlSsoUser validateLogin(String ossSessionId) {
        return SsoTokenLoginHelper.loginCheck(ossSessionId);
    }

    /**
     * Login
     *
     * @param request
     * @param redirectAttributes
     * @param username
     * @param password
     * @return
     */
    @RequestMapping("/doLogin")
    public String doLogin(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes, String username, String password, String ifRemember) {

        boolean ifRem = "on".equals(ifRemember);
        // valid login
        ReturnT<UserInfo> result = userService.findUser(username, password);
        if (result.getCode() != ReturnT.SUCCESS_CODE) {
            redirectAttributes.addAttribute("errorMsg", result.getMsg());
            redirectAttributes.addAttribute(TO_URL, request.getParameter(TO_URL));
            redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
            //return "redirect:/login";
            return "redirect:" + xxlSsoProperties.getLoginPage();
        }
        log.info("dologin ");

        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        String sessionId = getSessionId(xxlUser, result);

        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(request, response, sessionId, xxlUser, ifRem);

        // 4、return, redirect sessionId
        String redirectUrl = request.getParameter(Conf.REDIRECT_URL);
        String toUrl = request.getParameter(TO_URL);
        log.info("----url info----redirect url={}, to_url={}", redirectUrl, toUrl);

        if (redirectUrl != null && !redirectUrl.trim().isEmpty()) {
            String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId;
            if (!StringUtils.isEmpty(toUrl)) {
                redirectUrlFinal = redirectUrlFinal + "&" + TO_URL + "=" + toUrl;
            }
            return "redirect:" + redirectUrlFinal;
        } else {
            //return "redirect:/";
            return "redirect:" + xxlSsoProperties.getUserMgrPage();
        }

    }

    @ResponseBody
    @RequestMapping("/doLogin2")
    public BaseResult doLogin2(HttpServletRequest request, HttpServletResponse response, String username, String password, String ifRemember, String code, String redirectUrl, String toUrl, String captchaCode) {
        boolean ifRem = "on".equals(ifRemember);
        Map<String, String> map = new HashMap<>();
        try {
            // 验证码不为空，校验验证码，首次登录无验证码
            if (org.apache.commons.lang3.StringUtils.isNotEmpty(captchaCode)) {
                SsoWebLoginHelper.captchaCodeCheck(request, response, captchaCode);
            }
            // valid login
            ReturnT<UserInfo> result;
            if (StringUtils.isEmpty(code)) {
                //解密密码
                String decrypt = RSAUtils.decryptByPriKey(password, rsaPrivateKey);
                result = userService.findUser(username, decrypt);
            } else {
                // 钉钉登录
                result = userService.findUser(code);
            }
            if (result.getCode() != ReturnT.SUCCESS_CODE) {
                XxlSsoUser xxlUser = new XxlSsoUser();
                xxlUser.setUsername(username);
                sendLog("Login", xxlUser, request, result.getMsg());
                return BaseResult.buildError(result.getCode(), result.getMsg());
            }
            // 1、make xxl-sso user
            XxlSsoUser xxlUser = new XxlSsoUser();
            String sessionId = getSessionId(xxlUser, result);
            log.info("======================WebController doLogin2() SsoWebLoginHelper.login execute");
            // 3、login, store storeKey + cookie sessionId
            SsoWebLoginHelper.login(request, response, sessionId, xxlUser, ifRem);

            if (null == redirectUrl || redirectUrl.isEmpty()) {
                redirectUrl = xxlSsoProperties.getRedirectUrl();
            } else {
                redirectUrl = URLDecoder.decode(redirectUrl, ENC_UTF8);
            }
            if (null == toUrl || toUrl.isEmpty()) {
                toUrl = xxlSsoProperties.getToUrl();
            }
            sendLog("Login", xxlUser, request, null);
            String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId + "&" + TO_URL + "=" + toUrl;
            log.info("======================doLogin2 跳转 redirectUrlFinal:{}", redirectUrlFinal);
            map.put("redirectUrl", redirectUrlFinal);
            return BaseResult.buildSuccess(map);
        } catch (XxlSsoException xe) {
            log.error("WebController doLogin2 error:", xe);
            return BaseResult.buildError(xe.getMessage());
        } catch (Exception e) {
            log.error("WebController doLogin2 error:", e);
            map.put("redirectUrl", xxlSsoProperties.getLoginPage());
            return BaseResult.buildSuccess(map);
        }
    }

    @ResponseBody
    @RequestMapping("/doLogin3")
    public BaseResult<Object> doLogin3(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "username") String username, @RequestParam(value = "password") String password) {

        ReturnT<UserInfo> result = userService.findUser(username, password);
        if (result.getCode() != ReturnT.SUCCESS_CODE) {
            return BaseResult.buildError(result.getCode(), result.getMsg());
        }
        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        String sessionId = getSessionId(xxlUser, result);
        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(request, response, sessionId, xxlUser, false);
        return BaseResult.buildSuccess(xxlUser);

    }

    @GetMapping("/doMockLoginByEmployeeCode")
    public String doMockLoginByEmployeeCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String redirectUrl, @RequestParam String toUrl, @RequestParam String employeeCode, @RequestParam String ifRemember) {
        boolean ifRem = "on".equals(ifRemember);
        String loginUrl = toUrl;
        if (null == toUrl || toUrl.isEmpty()) {
            loginUrl = xxlSsoProperties.getToUrl();
        }
        try {
            if (StringUtils.isEmpty(employeeCode)) {
                log.error("@@@@@@WebController doMockLoginByEmployeeCode employeeCode is null");
                return "redirect:" + loginUrl;
            }
            String sessionId = generateCookie(request, response, employeeCode, ifRem);
            if (ObjectUtils.isEmpty(sessionId)) {//未登录跳转登录页
                log.error("@@@@@@WebController doMockLoginByEmployeeCode can not find user by employeeCode:{}", employeeCode);
                return "redirect:" + loginUrl;
            }
            // 4、return, redirect sessionId
            if (null == toUrl || toUrl.isEmpty()) {
                toUrl = xxlSsoProperties.getToUrl();
            }
            if (null == redirectUrl || redirectUrl.isEmpty()) {
                redirectUrl = xxlSsoProperties.getRedirectUrl();
            } else {
                redirectUrl = URLDecoder.decode(redirectUrl, ENC_UTF8);
            }
            String redirectUrlFinal = redirectUrl + "?" + Conf.SSO_SESSIONID + "=" + sessionId + "&" + TO_URL + "=" + toUrl;
            log.info("@@@@@@WebController doMockLoginByEmployeeCode redirectUrlFinal:{}", redirectUrlFinal);
            return "redirect:" + redirectUrlFinal;
        } catch (Exception e) {
            log.error("@@@@@@WebController doMockLoginByEmployeeCode error:", e);
            return "redirect:" + loginUrl;
        }
    }

    private String generateCookie(HttpServletRequest request, HttpServletResponse response, String employeeCode, boolean ifRem) throws Exception {
        ReturnT<UserInfo> result;
        String plainText = AESUtil.decrypt(employeeCode, AESUtil.keySeed);
        result = userService.findUserByEmployeeCode(plainText);
        if (result.getCode() != ReturnT.SUCCESS_CODE) {
            return null;
        }
        // 1、make xxl-sso user
        XxlSsoUser xxlUser = new XxlSsoUser();
        String sessionId = getSessionId(xxlUser, result);
        log.info("@@@@@@WebController doMockLoginByEmployeeCode sessionId:{}", sessionId);
        // 3、login, store storeKey + cookie sessionId
        SsoWebLoginHelper.login(request, response, sessionId, xxlUser, ifRem);
        return sessionId;
    }


    private String getSessionId(XxlSsoUser xxlUser, ReturnT<UserInfo> result) {
        UserInfo userInfo = result.getData();
        xxlUser.setUserid(String.valueOf(userInfo.getUserid()));
        xxlUser.setUsername(result.getData().getUsername());
        xxlUser.setUserCode(result.getData().getUserCode());
        xxlUser.setEmployeeId(result.getData().getEmployeeId());
        xxlUser.setVersion(UUID.randomUUID().toString().replaceAll("-", ""));
        //xxlUser.setExpireMinute(SsoLoginStore.getExpireMinute());
        xxlUser.setExpireMinute(XxlSsoCacheConfig.getCacheExpireMinute());
        xxlUser.setExpireFreshTime(System.currentTimeMillis());
        // 2、make session id
        return SsoSessionIdHelper.makeSessionId(xxlUser);
    }


    @GetMapping("/xbomLoginByEmployeeCode")
    public String doMockLoginByEmployeeCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String redirectUrl, @RequestParam String employeeCode) {
        String loginUrl = xxlSsoProperties.getToUrl();
        try {
            if (StringUtils.isEmpty(employeeCode)) {
                log.error("@@@@@@WebController doMockLoginByEmployeeCode employeeCode is null");
                return "redirect:" + loginUrl;
            }
            generateCookie(request, response, employeeCode, false);
            if (null == redirectUrl || redirectUrl.isEmpty()) {
                redirectUrl = xxlSsoProperties.getRedirectUrl();
            } else {
                redirectUrl = URLDecoder.decode(redirectUrl, ENC_UTF8);
            }
            log.info("@@@@@@WebController doMockLoginByEmployeeCode redirectUrlFinal:{}", redirectUrl);
            return "redirect:" + redirectUrl;
        } catch (Exception e) {
            log.error("@@@@@@WebController doMockLoginByEmployeeCode error:", e);
            return "redirect:" + loginUrl;
        }
    }

    /**
     * 获取图片验证码
     *
     * @param request
     * @param response
     */
    @ResponseBody
    @RequestMapping(value = "/getCaptcha", method = {RequestMethod.GET})
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) {
        try {
            CaptchaUtils.CaptchaDTO captchaDTO = CaptchaUtils.create();
            SsoWebLoginHelper.cacheCaptcha(request, response, captchaDTO.getCaptchaCode());
            ImageIO.write(captchaDTO.getBufferedImage(), "png", response.getOutputStream());
        } catch (Exception e) {
            log.error("验证码生成失败，e:{}", e.getMessage());
        }
    }

    @ResponseBody
    @GetMapping("/doGetLoginType")
    public BaseResult doGetLoginType() {
        LoginTypeInfo loginTypeInfo = new LoginTypeInfo();
        loginTypeInfo.setAccountSecret((!ObjectUtils.isEmpty(loginConfig.getAccountSecret()) && loginConfig.getAccountSecret()));
        loginTypeInfo.setDingDing((!ObjectUtils.isEmpty(loginConfig.getDingDing()) && loginConfig.getDingDing()));
        return BaseResult.buildSuccess(loginTypeInfo);
    }

    /**
     * 登出服务
     */
    @RequestMapping(Conf.SSO_LOGOUT)
    public String logout(HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        log.info("WebController.logout start");
        XxlSsoUser xxlSsoUser = SsoWebLoginHelper.loginCheck(request, response);
        // 1、清理cookie和redis
        SsoWebLoginHelper.logout(request, response);
        // 2、设置参数
        redirectAttributes.addAttribute(Conf.REDIRECT_URL, request.getParameter(Conf.REDIRECT_URL));
        if (!ObjectUtils.isEmpty(request.getParameter(Conf.TO_URL))) {
            redirectAttributes.addAttribute(Conf.TO_URL, request.getParameter(Conf.TO_URL));
        }
        // 3、判断重定向
        String redirectUrl = xxlSsoProperties.getLoginPage();
        if (StringUtils.isEmpty(matchedUrlsStr) || StringUtils.isEmpty(comacPortalUrl)) {
            log.info("WebController.logout matchedUrls or comacPortalUrl is empty, redirectUrl={}", redirectUrl);
            return "redirect:" + redirectUrl;
        }
        log.info("WebController.logout matchedUrlsStr={}, comacPortalUrl={}", matchedUrlsStr, comacPortalUrl);
        String[] matchedUrlAry = matchedUrlsStr.split(",");
        if (matchedUrlAry.length == 0) {
            log.info("WebController.logout matchedUrlAry is empty,redirectUrl={}", redirectUrl);
            return "redirect:" + redirectUrl;
        }
        String referer = request.getHeader("Referer");
        if (StringUtils.isEmpty(referer)) {
            log.info("WebController.logout referer is null, redirectUrl={}", redirectUrl);
            return "redirect:" + redirectUrl;
        }
        log.info("WebController.logout Referer={}", referer);
        for (String matchedUrl : matchedUrlAry) {
            if (referer.contains(matchedUrl)) {
                redirectUrl = comacPortalUrl;
                break;
            }
        }
        //课题专用
        if (!ObjectUtils.isEmpty(xxlSsoUser)) {
            sendLog("Logout", xxlSsoUser, request, null);
        } else {
            sendLog("Logout", new XxlSsoUser(), request, "当前用户已退出");
        }
        log.info("WebController.logout success,redirectUrl={}", redirectUrl);
        return "redirect:" + redirectUrl;
    }

    @ResponseBody
    @GetMapping("/getEncryptEmployeeCode")
    public String getEncryptCode(@RequestParam String employeeCode) throws Exception {
        if (StringUtils.isEmpty(employeeCode)) {
            return null;
        }
        return AESUtil.encrypt(employeeCode, AESUtil.keySeed);
    }


    @ResponseBody
    @GetMapping("/getCookieByEmployeeCode")
    public BaseResult<String> getCookieByEmployeeCode(HttpServletRequest request, HttpServletResponse response, @RequestParam String employeeCode) {
        BaseResult<String> baseResult = new BaseResult<>();
        if (StringUtils.isEmpty(employeeCode)) {
            baseResult.setCode(500);
            baseResult.setMessage("工号不能为空");
            return baseResult;
        }
        ReturnT<UserInfo> result = userService.findUserByEmployeeCode(employeeCode);
        if (result.getCode() == ReturnT.FAIL_CODE) {
            baseResult.setCode(500);
            baseResult.setMessage("未查询到该工号");
            return baseResult;
        }
        XxlSsoUser xxlUser = new XxlSsoUser();
        String sessionId = getSessionId(xxlUser, result);
        log.info("----WebController doMockLoginByEmployeeCode sessionId:{}", sessionId);
        // 3、login, store storeKey + cookie sessionId
        String storeKey = SsoSessionIdHelper.parseStoreKey(sessionId);
        if (storeKey == null) {
            throw new RuntimeException("parseStoreKey Fail, sessionId:" + sessionId);
        }
        SsoLoginStore.put(storeKey, xxlUser);
//        SsoWebLoginHelper.login(request, response, sessionId, xxlUser, false);
        baseResult.setCode(200);
        baseResult.setData(Conf.SSO_SESSIONID + "=" + sessionId);
        return baseResult;
    }

    @ResponseBody
    @PostMapping(value = "/getUserInfo")
    public BaseResult<UserInfo> getUserInfo(HttpServletRequest request, HttpServletResponse response) {

        // 判断当前用户和FO创建人是否匹配
        XxlSsoUser xxlSsoUser = SsoWebLoginHelper.loginCheck(request, response);

        if (xxlSsoUser == null) {
            return BaseResult.buildError("用户未登录");
        }
        log.info("XxlSsoUser{}", JSONObject.toJSONString(xxlSsoUser));
        UserInfo userInfo = userService.getUserInfo(Long.valueOf(xxlSsoUser.getUserid()));
        return BaseResult.buildSuccess(userInfo);
    }

    @ResponseBody
    @GetMapping(value = "/user/v1/metrics/registeredUserCount")
    public BaseResult<JSONObject> registeredUserCount(HttpServletRequest request) {
        Integer registeredUserCount = userService.getRegisteredUserCount();
        return BaseResult.buildSuccess(getMetrics("registeredUserCount", "注册用户数", "当前系统的用户注册数量统计", registeredUserCount));
    }

    @ResponseBody
    @GetMapping(value = "/user/v1/metrics/onlineUserCount")
    public BaseResult<JSONObject> onlineUserCount(HttpServletRequest request) {
        Set<String> cookies = JedisUtil.getByPrefix(Conf.SSO_SESSIONID);
        Set<Long> onlineUserCount = new HashSet<>();
        cookies.forEach(cookie -> {
            Long userId = SsoSessionIdHelper.extractUseIdFromSessionId(cookie);
            if (!ObjectUtils.isEmpty(userId)) {
                onlineUserCount.add(userId);
            }
        });
        return BaseResult.buildSuccess(getMetrics("onlineUserCount", "在线用户数", "当前系统的在线用户数量统计", onlineUserCount.size()));
    }

    private JSONObject getMetrics(String metricCode, String metricName, String metricNote, Integer number) {
        JSONObject object = new JSONObject();
        object.put("componentCode", "user");
        object.put("metricCode", metricCode);
        object.put("metricName", metricName);
        object.put("metricNote", metricNote);
        object.put("metricUnit", "人");
        JSONObject metrics = new JSONObject();
        object.put("metrics", Collections.singletonList(metrics));
        metrics.put("metricValue", number);
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String currentTime = LocalDateTime.now().format(formatter);
        metrics.put("metricTime", currentTime);
        return object;
    }

    private void sendLog(String logType, XxlSsoUser xxlUser, HttpServletRequest request, String failReason) {
        AuditLogin logObj = new AuditLogin();
        logObj.setLoginIp(IPUtils.getClientIP(request));
        logObj.setLoginType(logType);
        logObj.setUserId(xxlUser.getUserid());
        logObj.setUserName(xxlUser.getUsername());
        logObj.setLoginDevice(request.getHeader("User-Agent"));
        logObj.setLoginTime(new Date());
        if (!StringUtils.isEmpty(failReason)) {
            logObj.setLoginResult("FAIL");
            logObj.setFailReason(failReason);
        } else {
            logObj.setLoginResult("SUCCESS");
        }
        try {
            logHttpClient.asyncSendLoginLog(logObj);
        } catch (Exception e) {
            log.error("-----> sendLog error: {}", e.getMessage());
        }
    }
}
